package com.blockchain.console.service.common.achieve;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.digest.UnixCrypt;

import com.blockchain.common.enums.IsPass;
import com.blockchain.common.enums.LoginStatus;
import com.blockchain.console.service.common.LoginManage;
import com.blockchain.framework.http.session.authentication.AuthenticationException;
import com.blockchain.framework.service.ServiceFactory;
import com.blockchain.framework.service.ServiceResource;
import com.blockchain.framework.service.exception.LogicalException;
import com.blockchain.framework.service.exception.ParameterException;
import com.blockchain.util.StringHelper;

public class LoginManageImpl extends AbstractCommonService implements
		LoginManage {

	public static class LoginManageFactory implements
			ServiceFactory<LoginManage> {

		@Override
		public LoginManage newInstance(ServiceResource serviceResource) {
			return new LoginManageImpl(serviceResource);
		}
	}

	public LoginManageImpl(ServiceResource serviceResource) {
		super(serviceResource);
	}

	@Override
	public void log(int accountId, String ip) throws Throwable {
		String accountName = "";
		Timestamp now = new Timestamp(System.currentTimeMillis());
		String updateT7011 = "UPDATE T7011 SET F07=?,F08=? WHERE F01=?";
		try (Connection connection = getConnection()) {
			try (PreparedStatement ps = connection
					.prepareStatement("SELECT F02 FROM T7011 WHERE F01=?")) {
				ps.setInt(1, accountId);
				try (ResultSet rs = ps.executeQuery()) {
					if (rs.next()) {
						accountName = rs.getString(1);
					}
				}
			}
			try (PreparedStatement ps = connection
					.prepareStatement("INSERT INTO T7012 SET F02 = ?, F03 = ?, F04 = ?,F05 = ?")) {
				ps.setString(1, accountName);
				ps.setTimestamp(2, now);
				ps.setString(3, "Login "+ip);
				ps.setString(4, accountId <= 0 ? LoginStatus.SB.name()
						: LoginStatus.CG.name());
				ps.executeUpdate();
			}
		}
		execute(getConnection(), updateT7011, now, ip, accountId);
	}

	@Override
	public void updatePassWord(String oldPassWord, String newPassWord)
			throws Throwable {
		if (StringHelper.isEmpty(oldPassWord)) {
			throw new ParameterException("原密码不能为空！");
		}
		if (StringHelper.isEmpty(newPassWord)) {
			throw new ParameterException("新密码不能为空！");
		}
		int accountId = serviceResource.getSession().getAccountId();
		try (Connection conn = getConnection()) {
			try (PreparedStatement pst = conn
					.prepareStatement("SELECT F03 FROM T7011 WHERE F01 = ?")) {
				pst.setInt(1, accountId);
				try (ResultSet rst = pst.executeQuery()) {
					if (rst.next()) {
						String pwd = rst.getString(1);
						if (!UnixCrypt.crypt(oldPassWord,
								DigestUtils.sha256Hex(oldPassWord)).equals(pwd)) {
							throw new LogicalException("原密码错误");
						}
						if (pwd.equals(UnixCrypt.crypt(oldPassWord,
								DigestUtils.sha256Hex(newPassWord)))) {
							throw new LogicalException("修改的密码不能和原密码相同");
						}
					} else {
						throw new LogicalException("用户信息不存在");
					}
				}
			}
			try (PreparedStatement pst = conn
					.prepareStatement("UPDATE T7011 SET F03 = ? WHERE F01 = ?")) {
				pst.setString(
						1,
						UnixCrypt.crypt(newPassWord,
								DigestUtils.sha256Hex(newPassWord)));
				pst.setInt(2, accountId);
				pst.executeUpdate();
			}
			try (PreparedStatement ps = conn
					.prepareStatement("UPDATE T7011 SET F09=? WHERE F01=?")) {
				ps.setString(1, IsPass.F.name());
				ps.setInt(2, accountId);
				ps.executeUpdate();
			}
		}
	}

	@Override
	public int readAccountId(String accountName, String password)
			throws AuthenticationException, SQLException {
		int accountId = 0;
		String sql = "SELECT F01,F03,F05 FROM T7011 WHERE F02=?";
		try (Connection connection = getConnection()) {
			try (PreparedStatement ps = connection.prepareStatement(sql)) {
				ps.setString(1, accountName);
				try (ResultSet rs = ps.executeQuery()) {
					if (rs.next()) {
						accountId = rs.getInt(1);
						String pwd = rs.getString(2);
						String status = rs.getString(3);
						if ("TY".equals(status)) {
							throw new AuthenticationException("该账号被停用，禁止登录。");
						}
						if (!UnixCrypt.crypt(password,
								DigestUtils.sha256Hex(password)).equals(pwd)) {
							throw new AuthenticationException("用户名或密码错误.");
						}
					} else {
						throw new AuthenticationException("用户名或密码错误.");
					}
				}
			}
		}
		return accountId;
	}
}
